XX -- Apple II monitor dcmd for the Apple IIe Card
Purpose
Macsbug (Apple's debugger for the Macintosh) lets the user add custom commands by adding special resources of the type 'dcmd' (which stands for "debugger command"). These commands can be used just like the built-in commands and can even take parameters from the command line.
The XX dcmd allows you to examine and change the contents of "Apple II" memory on a Macintosh LC with an Apple IIe Card (from within Macsbug, the Macintosh debugger). It uses a command syntax like that of the Apple IIe and IIGS monitors. Note that it does NOT allow you to step or trace through Apple II code like some versions of the Apple II monitor.
Installation
You must install Macsbug (preferably version 6.0 or later) in your Macintosh LC's System Folder. Don't forget to put the "Debugger Prefs" file in the System Folder, too. Copy the 'dcmd' resource from the "XX" file into your Debugger Prefs file; the paragraph below describes how to do this with ResEdit.
Launch the ResEdit application. Open the "XX" file and copy the 'dcmd' resource (this is the only resource in the file). Close the "XX" file. Open the "Debugger Prefs" file in the System Folder. Paste the resource in and save the file. Quit ResEdit. When you restart, the xx dcmd will be available.
Using XX
To use the command, go into Macsbug (you can do this by pressing the interrupt switch on the Macintosh's programmer's switch). From Macsbug, type "xx" and a space followed by an Apple II monitor-style command line. You can use upper or lower case or both. The sections below describe in greater detail the commands that are supported. Here is an example command line:
xx 800:20 0 BF 42 0 9 60 N 800L \"happy"\<800.BFFFP 2340,20
This command line stores some values at $800 in the main memory bank, shows a disassembly of what was just stored, searches a portion of the main bank for the word "happy", and dumps locations $2340 through $235F.
Help
You can get a brief summary of commands supported by XX by typing either of the following lines from Macsbug:
?xx
help xx
Numbers
All numbers (including addresses) must be given in hexadecimal, without any leading "$" or "0x". You may use either upper or lower case letters or a mixture of both. Any number of hex digits can be used, but only the low order 8 digits (32 bits) are ever used. You can use Macsbug to convert between decimal and hexadecimal and to do simple math; see the Macsbug Reference for more information.
Addresses
Addresses are numbers with up to 5 significant digits (you can have more leading digits but they will be ignored). The 5th digit is a bank byte (much like in the IIGS monitor, only it doesn't require a slash, "/", to separate the bank from the rest of the address). Bank 0 is the main memory bank, bank 1 is the auxilliary memory bank.
The bank-switched language card memory that the Apple II accesses at $D000-$DFFF can be accessed at $C000-$CFFF for the first bank and $D000-$DFFF for the second bank. You cannot access the I/O softswitches from XX.
Ranges
Some commands operate on a range of addresses (like filling or dumping memory). The range can be specified by a first address and a last address separated by a period (the normal Apple II monitor syntax). You can also specify the range by using the first address and the length of the range separated by a comma. For example, the 800.8FF and 800,100 specify the same range. Note that the List command uses the comma form differently (see below).
Patterns
Both the memory store and the pattern search commands require the use of a pattern. A pattern is simply a list of numbers and/or strings separated by spaces. Patterns are assumed to be 255 bytes or less; a longer pattern will probably cause the dcmd to crash horribly. In the case of the pattern search command, the whole pattern is enclosed by backward slash characters (\) before and after the pattern.
When numbers appear in patterns, the number of bytes they occupy depends on how many digits were used (including leading zeros). Numbers always occupy 1, 2, or 4 bytes. The following examples show some numbers as they would appear in a pattern and the bytes they would generate in the pattern:
9 09
001 01 00
1234 34 12
01234 34 12 00 00
12345678 78 56 34 12
Three kinds of character strings are supported in patterns. Strings enclosed in single quotes (') have their high order bit set; strings enclosed in double quotes (") don't have their high bit set. Single and double quote strings have neither a leading length byte nor a terminating zero byte. Strings enclosed in square brackets ([,]) don't have their high bit set, but do have a length byte preceding them (i.e. they are Pascal-style strings).
The Next Address
XX maintains a notion of the next address (to display or modify). For some of the commands, you can omit an address or range; the next address will be used instead. The next address is shared by all commands that allow it (i.e. there aren't separate next addresses for dumping and storing -- this is different from the real Apple II monitor). These commands also set the next address to the address they would have operated on next (i.e. the next address that would have been dumped, modified, listed).
Dumping memory
Memory dumps can display up to 16 bytes per line. The address corresponding to the start of the line is shown, followed by up to 16 bytes in hex followed by spaces, and finally the same bytes displayed as text (the high bit is ignored so that you can see ASCII text that has its high bit set). Unprintable (control) characters are displayed as bullet characters (•).
If supply an empty command line, XX will dump 16 bytes from the "next address". If you use just an address, it will dump 16 bytes from the given address. If you use a range, it will dump all the bytes in the range, 16 per line. In all cases, the "next address" is set to the byte that would be dumped next.
Modifying (storing) memory (:)
You can modify memory by using an address (the "next address" is used if none is given) followed by a colon (:) and a pattern. Any invalid characters in the pattern are assumed to be other commands, so the pattern is terminated and the characters are left to be processed after the memory is modified. The memory that is modified is then dumped back so you can see the exact bytes stored.
Zap (Fill) memory (Z)
The Z command lets you set all the bytes in a given range to a given value. The form of the command is:
value<rangeZ
where the least significant byte of "value" is put in every byte in "range" ("range" can be first address, period, last address or first address, comma, length). For example:
0<350,4Z
stores zeroes in the bytes at addresses $350, $351, $352, and $353 in the main memory bank.
List (disassemble) code (L)
The L command atttempts to disassemble instructions at the given address or range. It supports the 65C02 instruction set. A JSR to $BF00 (i.e. a call to the ProDOS 8 MLI) is treated specially; it will also show the following byte and word (command number and parameter block address). The JSR instruction and following byte and word are all considered to be a single instruction.
If no address is given, it lists 16 instructions from the "next address." If a single address is given, it lists 16 instructions from the given address. If a period-separated range is given, the instructions in that address range are listed. If a comma-separated range is given, the first number is the starting address and the second number is the number of instructions that will be listed (NOTE: this use of a comma-separated range is different from other commands).
Moving memory (M)
Memory can be copied (moved) to another area of memory. The general form of the command is:
dest<rangeM
where "dest" is a single address where the memory will be copied to, and "range" is the address range (period or comma separated) of the memory that will be copied (i.e. the source).
Verifying memory (V)
You can compare the contents of one range of memory to another range of memory and display any bytes that differ along with their addresses. The general form of the command is:
dest<rangeV
where "dest" is the start of the destination (comparison) range and "range" is the address range of the source. If any byte in the source range does not equal the corresponding byte in the destination, the address and value of the source byte will be displayed and the value of the corresponding destination byte will be displayed in parentheses.
Copying from Macintosh to Apple II memory (R)
You can copy a range of bytes from Macintosh memory into Apple II memory. The "R" stands for "Read" (as if you were reading from Macintosh memory). The general form of the command is:
mac<rangeR
where "mac" is the address of the start of the Macintosh memory that will be read and "range" is the address range in Apple II memory where the data will be stored.
Copying from Apple II memory to Macintosh memory (W)
You can copy a range of bytes from Apple II memory into Macintosh memory. The "W" stands for "Write" (as if you were writing to Macintosh memory). The general form of the command is:
mac<rangeW
where "mac" is the starting address in Macintosh memory where the data will be stored and "range" is the address range in Apple II memory that will be copied.
Pattern search (P)
The P command lets you search for a given pattern in Apple II memory. The general form of the command is:
\pattern\<rangeP
where "pattern" is a pattern as described above and "range" is the address range that will be searched for "pattern". For every occurence of the pattern that is found, the starting address of the occurrence is displayed. The occurrence must be completely contained within the range (if the start of the pattern is found at the end of the range, it is not considered a match). Overlapping occurrences are not found; for example, if the text "bobob" is in memory, searching for "bob" will find the first three characters, but not the last three (since it started searching for a new occurrence at the second "o").
No Operation (N)
The command is simply the letter N; it takes no parameters. This comes from the old Normal command (which causes output not to be displayed in inverse or flashing text). With XX, this command does nothing. It is useful primarily to separate commands, especially the dump or store commands. For example, the following commands store some bytes and then disassembles them; the N command is used to terminate the store command so that the address of the list command won't be stored as data:
800:AD 0 C0 10 FB 8D 10 C0 N 800,3L
Mini-assembler
Sorry, the mini-assembler is not supported. This is mostly due to a lack of a reasonably clean, unambiguous syntax. If someone comes up with a good syntax for the mini-assembler functionality, I'll try to incorporate it into a future version of XX. Remember, the semicolon (;) can't be used (Macsbug uses it to separate commands) and a dcmd can't do line input (everything has to go on the command line). It would be a bummer to be restricted to one instruction per command line. Make sure you can handle the case of an ASL (accumulator) instruction followed by an ADC instrucion and that the ADC can't be confused with the operand of the ASL and that the operand of the ADC can't be confused with a new address to store to (it would be nice to allow you to specify an address to store to without having to use a new command line or to exit and re-enter the miniassembler).
Step, Trace, Go, etc.
The Apple IIe Card is really a coprocessor card (with its own 65C02 CPU). The Macintosh has no direct control over the CPU itself and cannot directly access registers on the CPU. Therefore, the Step, Trace, Go and register display/modification commands of the Apple II monitor are not supported.